// include
#include "timer_os.h"
#include "timer_os_serives.h"

// define

// variable
static rt_tick_t timerOsTick = 0;
static void      cola_task_loop(void);

static rt_slist_t os_timer_list_head;

static volatile uint8_t task_num = 0;
// function
rt_base_t TimerOsInterruptDisable(void) {
    return RT_EOK;
}
rt_base_t TimerOsInterruptEnable(rt_base_t level) {
    return RT_EOK;
}

rt_tick_t TimerOsGetTick(void) {
    /* return the global tick */
    return timerOsTick;
}

/**
 * This function will set current tick
 */
void TimerOsSetTick(rt_tick_t tick) {
    rt_base_t level;

    level   = TimerOsInterruptDisable();
    timerOsTick = tick;
    TimerOsInterruptEnable(level);
}

void TimerOsTickIncrease(void) {
    /* increase the global tick */
    ++timerOsTick;
    cola_task_loop();
}

int TimerOsInit(void) {
    rt_slist_init(&os_timer_list_head);
    return RT_EOK;
}

int TimerOsStartUp(st_timer_os_t task) {
    task->timerOsState = EM_OS_TIMER_RUN;
    return RT_EOK;
}
/*

@return :RT_EOK or RT_ERROR
*/
int TimerOsCreate(st_timer_os_t task, const TimerOsCallBack func, uint32_t in_tick) {
    rt_slist_init(&task->tlist);

    rt_base_t level;
    level = TimerOsInterruptDisable();

    if (RT_NULL == task) {
        TimerOsInterruptEnable(level);
        return RT_ERROR;
    }
    task->timerOsState    = EM_OS_TIMER_STOP;
    task->func        = func;
    task->event.event = 0;
    task->initTick = task->remainingTick = in_tick;
    task->timerOsNum                         = task_num++;

    rt_slist_insert(&os_timer_list_head, &task->tlist);

    TimerOsInterruptEnable(level);
    return RT_EOK;
}

/*

*/
int TimerOsDelete(st_timer_os_t task) {
    rt_base_t level;
    level = TimerOsInterruptDisable();
    if (task->timerOsState == EM_OS_TIMER_STOP)
        return RT_EOK;

    /* change stat */
    task->timerOsState = EM_OS_TIMER_STOP;

    rt_slist_remove(&os_timer_list_head, &(task->tlist));

    TimerOsInterruptEnable(level);
    return RT_EOK;
}
/*

*/
static void cola_task_loop(void) {
    uint32_t events;

    st_timer_os_t tmpTimer = RT_NULL;

    rt_slist_for_each_entry(tmpTimer, &os_timer_list_head, tlist) {
        tmpTimer->remainingTick--;
        if (tmpTimer->remainingTick == 0) {
            tmpTimer->remainingTick = tmpTimer->initTick;

            if (tmpTimer->timerOsState == EM_OS_TIMER_RUN) {
                if (RT_NULL != tmpTimer->func) {
                    events = tmpTimer->event.event;
                    if (events) {
                        rt_base_t level;
                        level                 = TimerOsInterruptDisable();
                        tmpTimer->event.event = 0;
                        TimerOsInterruptEnable(level);
                    }
                    tmpTimer->func(tmpTimer->event);
                }
            }
        }
    }
}
